package cn.fnst.facecomp.sign;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import cn.fnst.facecomp.model.ComparePhotoTicket;
import cn.fnst.facecomp.utils.Utils;
import net.sf.json.JSONObject;

public class TokenService {
//	public static final String APPID = "wxab8e741fe58c73a6";	
//	private static final String SECRET = "39925a1f3a75d3d77e4be879c1b7f283";
	public static final String APPID = "wx1e2b841a1889419c";	
	private static final String SECRET = "8d36f061bcf933d637ce917315dac913";
	
//	public static final String APPID = "wx35961426dd3ebc0f";	
//	private static final String SECRET = "d4624c36b6795d1d99dcf0547af5443d";
	
	private static final String	JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
	
	protected Logger logger = Logger.getLogger(getClass());
	
	protected static SqlMapClient sqlMapClient;
	
	private static TokenService instance;
	
	private ComparePhotoTicket ticket;
	
	public static synchronized TokenService getInstance() throws Exception{
		if(instance == null){
			instance = new TokenService();
		}
		return instance;
	}
	
	public TokenService() throws Exception{
		Reader reader = Resources.getResourceAsReader ("SqlMapConfig.xml");
		sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
	}
	
	public String getNewAccessToken(){
		String result = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
        	StringBuilder urlSb = new StringBuilder();
        	urlSb.append("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=");
        	urlSb.append(APPID);
        	urlSb.append("&secret=");
        	urlSb.append(SECRET);
            
            HttpGet httpGet = new HttpGet(urlSb.toString());
            CloseableHttpResponse response = httpclient.execute(httpGet);
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            String resultJsonStr = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
            //result = resultJsonStr;
            
            JSONObject jsonObject = JSONObject.fromObject(resultJsonStr);
			logger.info("jsonObject: " + jsonObject);
			result = jsonObject.getString("access_token");
			logger.info("access token[" + result + "]");
        }catch(Exception e){
        	e.printStackTrace();
        } finally {
            try {
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
        return result;
	}
	
	public String getJsApiTicketByWX(String token) {
		String jsAPITicktUrl = JSAPI_TICKET_URL + "&access_token=" + token;
		String jsAPITick = null;
		try {
			StringBuffer sTotalString = getJsonStringByConnection(jsAPITicktUrl);
			JSONObject jsonObject = JSONObject.fromObject(sTotalString.toString());
			logger.info("jsonObject: " + jsonObject);
			jsAPITick = jsonObject.getString("ticket");
			logger.info("jsapiTicket[" + jsAPITick + "]");
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return jsAPITick;
	}
	
	protected StringBuffer getJsonStringByConnection(String urlString) throws MalformedURLException, IOException {
		logger.debug("urlString:" + urlString);
		URL url = new URL(urlString);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		InputStream urlStream = connection.getInputStream();
		connection.setConnectTimeout(2000);
		connection.setReadTimeout(5000);
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlStream,
				Charset.forName("UTF-8")));
		StringBuffer sTotalString = new StringBuffer();
		String sCurrentLine = "";
		while ((sCurrentLine = bufferedReader.readLine()) != null) {
			sTotalString.append(sCurrentLine);
		}
		bufferedReader.close();
		connection.disconnect();
		return sTotalString;
	}
	
	public ComparePhotoTicket getLatestTicket() throws Exception{
		List list = sqlMapClient.queryForList("face.getLatestComparePhotoTicket");
		if(list == null || list.size() == 0){
			return null;
		}		
		ComparePhotoTicket cpTicket = (ComparePhotoTicket) list.get(0);
		return cpTicket;
	}
	
	public void insertComparePhotoTicket(ComparePhotoTicket ticket) throws Exception{
		sqlMapClient.insert("face.insert_comparePhotoTicket", ticket);
	}
	
	public String getTicket() throws Exception{
		if(ticket != null && !ticket.isExpired()){
			return ticket.getJsapiTicket();
		}
		ticket = getLatestTicket();
		if(ticket != null && !ticket.isExpired()){
			return ticket.getJsapiTicket();
		}
		ticket = createNewTicket();
		return ticket.getJsapiTicket(); 
	}
	
	private ComparePhotoTicket createNewTicket() throws Exception{
		String accessToken = getNewAccessToken();
		String jsapiTicket = getJsApiTicketByWX(accessToken);
		String requestTime = Utils.getTimeString(new Date());
		
		ComparePhotoTicket newTicket = new ComparePhotoTicket();
		newTicket.setAccessToken(accessToken);
		newTicket.setJsapiTicket(jsapiTicket);
		newTicket.setRequestTime(requestTime);
		insertComparePhotoTicket(newTicket);
		return newTicket;
	}
	
	public static void main(String[] args) throws Exception{
		TokenService ss = new TokenService();
		String ticket = ss.getTicket();
		ticket = ss.getTicket();
		System.out.println(ticket);
	}
}
